package com.xnyzc.lhy.mis.service.impl.approval;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xnyzc.lhy.common.component.config.GlobalConfig;
import com.xnyzc.lhy.common.entity.Qd;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.approval.EApprovalMatter;
import com.xnyzc.lhy.common.penum.approval.EApproverType;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.common.util.ListToTreeUtil;
import com.xnyzc.lhy.common.util.TokenUtil;
import com.xnyzc.lhy.mis.entity.approval.OaApprovalOffice;
import com.xnyzc.lhy.mis.entity.approval.OaApprovalTempChild;
import com.xnyzc.lhy.mis.entity.approval.OaApprovalTempPrimary;
import com.xnyzc.lhy.mis.entity.param.approval.ApprovalTempInfoParam;
import com.xnyzc.lhy.mis.entity.param.approval.ApprovalTempNodeInfo;
import com.xnyzc.lhy.mis.entity.result.approval.OaApprovalTempResult;
import com.xnyzc.lhy.mis.entity.sidebar.OaSysOffice;
import com.xnyzc.lhy.mis.entity.system.OaSysUser;
import com.xnyzc.lhy.mis.mapper.approval.OaApprovalOfficeMapper;
import com.xnyzc.lhy.mis.mapper.approval.OaApprovalTempChildMapper;
import com.xnyzc.lhy.mis.mapper.approval.OaApprovalTempPrimaryMapper;
import com.xnyzc.lhy.mis.mapper.sidebar.OaSysOfficeMapper;
import com.xnyzc.lhy.mis.service.approval.IOaApprovalOfficeService;
import com.xnyzc.lhy.mis.service.approval.IOaApprovalTempChildService;
import com.xnyzc.lhy.mis.service.approval.IOaApprovalTempPrimaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 审批流模板主表 服务实现类
 * </p>
 *
 * @author huxuekuo
 * @since 2019-08-07
 */
@Service
public class OaApprovalTempPrimaryServiceImpl extends ServiceImpl<OaApprovalTempPrimaryMapper, OaApprovalTempPrimary> implements IOaApprovalTempPrimaryService {


    @Autowired
    private OaApprovalTempPrimaryMapper oaApprovalTempPrimaryMapper;

    @Autowired
    private OaApprovalOfficeMapper oaApprovalOfficeMapper;

    @Autowired
    private IOaApprovalOfficeService iOaApprovalOfficeService;

    @Autowired
    private OaSysOfficeMapper oaSysOfficeMapper;

    @Autowired
    private OaApprovalTempChildMapper oaApprovalTempChildMapper;

    @Autowired
    private IOaApprovalTempChildService iOaApprovalTempChildService;

    /**
     * 获取审批流模板列表
     *
     * @param companyNameSearch
     * @param approvalNameSearch
     * @param page
     * @param tag
     * @return
     */
    @Override
    public Rv getCmsApprovalTempList(String companyNameSearch, String approvalNameSearch, Integer page, String tag) {
        List<String> scopeData = TokenUtil.getRoleDataScope();
        if (CheckUtil.objIsEmpty(scopeData)) {
            throw new PangException(EErrorCode.currentSysUserNoDataError);
        }
        Long companyId = null;
        // 用户数据公司权限
        for (String s : scopeData) {
            if (Objects.equals(s, GlobalConfig.DATA_SCOPE_COMPANY_AND_CHILD) || Objects.equals(s, GlobalConfig.DATA_SCOPE_COMPANY)) {
                OaSysUser oaSysUser = (OaSysUser) TokenUtil.getTokenUserEntity(OaSysUser.class);
                companyId = oaSysUser.getCompanyId();
            }
        }

        IPage<OaApprovalTempResult> iPage = new Page<>();
        iPage.setCurrent(page);
        IPage<OaApprovalTempResult> oaApprovalTempPrimaryPage = oaApprovalTempPrimaryMapper.selectApprovalTempPage(iPage, tag, companyNameSearch, approvalNameSearch, companyId);
        List<OaApprovalTempResult> oaApprovalTempResultList = oaApprovalTempPrimaryPage.getRecords();

        if (!CheckUtil.objIsEmpty(oaApprovalTempResultList)) {
            StringBuilder approvalIdSb = new StringBuilder();
            for (OaApprovalTempResult otr : oaApprovalTempResultList) {
                approvalIdSb.append(otr.getApprovalId()).append(",");
            }
            if (!CheckUtil.objIsEmpty(approvalIdSb)) {
                String approvalIdStr = approvalIdSb.toString().substring(0, approvalIdSb.length() - 1);
                List<Map<String, Object>> linkOfficeList = oaApprovalTempPrimaryMapper.selectLinkOffice(approvalIdStr);
                if (!CheckUtil.objIsEmpty(linkOfficeList)) {
                    for (int i = 0; i < oaApprovalTempResultList.size(); i++) {
                        OaApprovalTempResult atr = oaApprovalTempResultList.get(i);
                        StringBuilder sb = new StringBuilder();
                        for (Map<String, Object> m : linkOfficeList) {
                            if (Objects.equals(atr.getApprovalId(), m.get("approvalId"))) {
                                sb.append(m.get("officeName")).append("、");
                            }
                        }
                        oaApprovalTempResultList.get(i).setUseDept(String.valueOf(sb));
                    }
                }
            }
            oaApprovalTempPrimaryPage.setRecords(oaApprovalTempResultList);
        }

        return Rv.wrap(oaApprovalTempPrimaryPage);
    }

    /**
     * 获取公司下的部门
     *
     * @param companyId
     * @return
     */
    @Override
    public Rv getCmsLinkOfficeList(Long companyId) {

        List<OaSysOffice> oaSysOffices = oaApprovalTempPrimaryMapper.getCmsLinkOfficeList(companyId);
        JSONArray dataResult = new JSONArray();
        if (!CheckUtil.objIsEmpty(oaSysOffices)) {
            List<Map<String, Object>> officeMapList = ListToTreeUtil.getOfficeList(oaSysOffices, new ArrayList<>(), "");
            dataResult = ListToTreeUtil.listToTree(JSONArray.parseArray(JSON.toJSONString(officeMapList)), "value", "pId", "children");
        }
        return Rv.wrap(dataResult);
    }

    @Override
    public Rv saveLinkOffice(Long companyId, String checkNodes, Long approvalId) {

        String tag = TokenUtil.getTag();
        Long userId = TokenUtil.getTokenUserId();
        String[] officeIds = checkNodes.split(",");
        List<Long> officeIdList = new ArrayList<>();
        for (String s : officeIds) {
            if (!Objects.equals(s, String.valueOf(companyId))) {
                officeIdList.add(Long.valueOf(s));
            }
        }

        // 先删后台增
        QueryWrapper<OaApprovalOffice> oaApprovalOfficeQueryWrapper = new QueryWrapper<>();
        oaApprovalOfficeQueryWrapper.in(OaApprovalOffice.OFFICE_ID, officeIdList);
        oaApprovalOfficeQueryWrapper.or().eq(OaApprovalOffice.APPROVAL_ID, approvalId);
        oaApprovalOfficeMapper.delete(oaApprovalOfficeQueryWrapper);

        Date date = new Date();

        List<OaApprovalOffice> oaApprovalOffices = new ArrayList<>();
        for (Long officeId : officeIdList) {
            OaApprovalOffice oao = new OaApprovalOffice();
            Long id = IDUtil.nextId();
            oao.setLinkedId(id);
            oao.setApprovalId(approvalId);
            oao.setOfficeId(officeId);
            oao.setApplyMatter(0);
            oao.setTag(tag);
            oao.setCreateTime(date);
            oao.setCreateUser(userId);
            oao.setUpdateUser(userId);
            oao.setUpdateTime(date);
            oaApprovalOffices.add(oao);
        }

        // 批量插入
        iOaApprovalOfficeService.saveBatch(oaApprovalOffices);

        return Rv.wrap(EErrorCode.success);
    }

    /**
     * 获取当前登录人的公司列表
     *
     * @return
     */
    @Override
    public Rv getCmsUserCompanyList() {

        List<String> scopeData = TokenUtil.getRoleDataScope();
        if (CheckUtil.objIsEmpty(scopeData)) {
            throw new PangException(EErrorCode.currentSysUserNoDataError);
        }
        Long companyId = null;
        // 用户数据公司权限
        for (String s : scopeData) {
            if (Objects.equals(s, GlobalConfig.DATA_SCOPE_COMPANY_AND_CHILD) || Objects.equals(s, GlobalConfig.DATA_SCOPE_COMPANY)) {
                OaSysUser oaSysUser = (OaSysUser) TokenUtil.getTokenUserEntity(OaSysUser.class);
                companyId = oaSysUser.getCompanyId();
            }
        }

        QueryWrapper<OaSysOffice> oaSysOfficeQueryWrapper = new QueryWrapper<>();
        oaSysOfficeQueryWrapper.eq(OaSysOffice.TYPE, 1);
        if (!CheckUtil.objIsEmpty(companyId)) {
            oaSysOfficeQueryWrapper.eq(OaSysOffice.OFFICE_ID, Long.valueOf(companyId));
        }

        List<OaSysOffice> oaSysOfficeList = oaSysOfficeMapper.selectList(oaSysOfficeQueryWrapper);

        List<Qd> qdList = new ArrayList<>();
        if (!CheckUtil.objIsEmpty(oaSysOfficeList)) {
            for (OaSysOffice oso : oaSysOfficeList) {
                Qd qd = Qd.create().add("code", oso.getOfficeId()).add("name", oso.getName());
                qdList.add(qd);
            }
        }

        return Rv.wrap(qdList);
    }

    /**
     * 获取公司下的成员
     *
     * @param companyCode
     * @return
     */
    @Override
    public Rv getSpecialUserList(Long companyCode) {

        List<Map<String, Object>> userInfoList = oaApprovalTempPrimaryMapper.getUserInfoList(companyCode);

        return Rv.wrap(userInfoList);
    }

    /**
     * 保存审批节点信息
     *
     * @return
     */
    @Override
    public Rv saveApprovalTempInfo(ApprovalTempInfoParam approvalTempInfoParam) {

        Date date = new Date();
        String tag = TokenUtil.getTag();
        // 插入
        if (CheckUtil.objIsEmpty(approvalTempInfoParam.getApprovalId())) {
            Long id = IDUtil.nextId();

            OaApprovalTempPrimary oaApprovalTempPrimary = new OaApprovalTempPrimary();
            oaApprovalTempPrimary.setApprovalId(id);
            oaApprovalTempPrimary.setApprovalName(approvalTempInfoParam.getApprovalName());
            oaApprovalTempPrimary.setCompanyId(approvalTempInfoParam.getCompanyCode());
            // 暂时只支持打车审批流
            oaApprovalTempPrimary.setApprovalMatter(EApprovalMatter.takeATaxi.getValue());
            oaApprovalTempPrimary.setApprovalRemark(approvalTempInfoParam.getApprovalRemark());
            oaApprovalTempPrimary.setIsEnable(1);
            oaApprovalTempPrimary.setTag(tag);
            oaApprovalTempPrimary.setCreateUser(id);
            oaApprovalTempPrimary.setCreateTime(date);
            oaApprovalTempPrimary.setUpdateTime(date);
            oaApprovalTempPrimary.setUpdateUser(id);

            List<OaApprovalTempChild> oaApprovalTempChildList = new ArrayList<>();
            List<ApprovalTempNodeInfo> nodeListInfo = approvalTempInfoParam.getNodeList();
            // 节点
            Integer node = 1;
            for (ApprovalTempNodeInfo atn : nodeListInfo) {
                if (!CheckUtil.objIsEmpty(atn.getType())) {
                    OaApprovalTempChild ot = new OaApprovalTempChild();
                    Long childId = IDUtil.nextId();
                    ot.setChildId(childId);
                    ot.setApprovalId(id);
                    ot.setIsParallel(0);
                    ot.setApprovalNode(node++);
                    ot.setApproverId(atn.getUserIds());
                    ot.setExpand1(atn.getInitiator());
                    ot.setExpand2(atn.getName());
                    ot.setTag(tag);
                    ot.setCreateTime(date);
                    ot.setCreateUser(childId);
                    ot.setUpdateTime(date);
                    ot.setUpdateUser(childId);
                    childInfo(atn, ot);
                    oaApprovalTempChildList.add(ot);
                }
            }
            // 插入
            oaApprovalTempPrimaryMapper.insert(oaApprovalTempPrimary);
            iOaApprovalTempChildService.saveBatch(oaApprovalTempChildList);
        }
        // 更新
        else {
            Long userId = TokenUtil.getTokenUserId();
            OaApprovalTempPrimary oaApprovalTempPrimary = new OaApprovalTempPrimary();
            oaApprovalTempPrimary.setApprovalId(Long.valueOf(approvalTempInfoParam.getApprovalId()));
            oaApprovalTempPrimary.setApprovalName(approvalTempInfoParam.getApprovalName());
            oaApprovalTempPrimary.setCompanyId(approvalTempInfoParam.getCompanyCode());
            // 暂时只支持打车审批流
            oaApprovalTempPrimary.setApprovalMatter(EApprovalMatter.takeATaxi.getValue());
            oaApprovalTempPrimary.setApprovalRemark(approvalTempInfoParam.getApprovalRemark());
            oaApprovalTempPrimary.setIsEnable(1);
            oaApprovalTempPrimary.setUpdateTime(date);
            oaApprovalTempPrimary.setUpdateUser(userId);
            oaApprovalTempPrimaryMapper.updateById(oaApprovalTempPrimary);

            // 删除原先
            QueryWrapper<OaApprovalTempChild> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(OaApprovalTempChild.APPROVAL_ID, approvalTempInfoParam.getApprovalId());
            oaApprovalTempChildMapper.delete(queryWrapper);

            // 节点
            List<OaApprovalTempChild> oaApprovalTempChildList = new ArrayList<>();
            List<ApprovalTempNodeInfo> nodeListInfo = approvalTempInfoParam.getNodeList();
            // 节点
            Integer node = 1;
            for (ApprovalTempNodeInfo atn : nodeListInfo) {
                if (!CheckUtil.objIsEmpty(atn.getType())) {
                    OaApprovalTempChild ot = new OaApprovalTempChild();
                    Long childId = IDUtil.nextId();
                    ot.setChildId(childId);
                    ot.setApprovalId(Long.valueOf(approvalTempInfoParam.getApprovalId()));
                    ot.setIsParallel(0);
                    ot.setApprovalNode(node++);
                    ot.setApproverId(atn.getUserIds());
                    ot.setExpand1(atn.getInitiator());
                    ot.setExpand2(atn.getName());
                    ot.setTag(tag);
                    ot.setCreateTime(date);
                    ot.setCreateUser(childId);
                    ot.setUpdateTime(date);
                    ot.setUpdateUser(childId);
                    childInfo(atn, ot);
                    oaApprovalTempChildList.add(ot);
                }
            }
            iOaApprovalTempChildService.saveBatch(oaApprovalTempChildList);
        }
        return Rv.wrap(EErrorCode.success);
    }

    /**
     * 设置更新审批子表信息
     *
     * @param atn
     * @param ot
     */
    private void childInfo(ApprovalTempNodeInfo atn, OaApprovalTempChild ot) {
        if (Objects.equals(atn.getType(), "0")) {
            ot.setApproverType(EApproverType.designatedMember.getValue());
            if (atn.getChecked()) {
                ot.setIsParallel(1);
            }
        } else if (Objects.equals(atn.getType(), "1")) {
            ot.setApproverType(EApproverType.role.getValue());
            if (atn.getChecked()) {
                ot.setIsParallel(1);
            }
        } else if (Objects.equals(atn.getType(), "2")) {
            ot.setApproverType(EApproverType.supervisor.getValue());
        } else if (Objects.equals(atn.getType(), "3")) {
            ot.setApproverType(EApproverType.sponsor.getValue());
        }
    }

    /**
     * 获取审批流详情
     *
     * @param approvalId
     * @return
     */
    @Override
    public Rv getOaApprovalPrimaryInfo(Long approvalId) {

        // 查询主表信息
        OaApprovalTempPrimary oaApprovalTempPrimary = oaApprovalTempPrimaryMapper.selectById(approvalId);
        // 查询子表节点信息
        QueryWrapper<OaApprovalTempChild> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaApprovalTempChild.APPROVAL_ID, approvalId);
        queryWrapper.orderByAsc(OaApprovalTempChild.APPROVAL_NODE);
        List<OaApprovalTempChild> oaApprovalTempChildList = oaApprovalTempChildMapper.selectList(queryWrapper);

        ApprovalTempInfoParam approvalTempInfoParam = new ApprovalTempInfoParam();
        approvalTempInfoParam.setApprovalName(oaApprovalTempPrimary.getApprovalName());
        approvalTempInfoParam.setCompanyCode(oaApprovalTempPrimary.getCompanyId());
        approvalTempInfoParam.setApprovalRemark(oaApprovalTempPrimary.getApprovalRemark());
        approvalTempInfoParam.setApprovalId(String.valueOf(oaApprovalTempPrimary.getApprovalId()));

        List<ApprovalTempNodeInfo> nodeList = new ArrayList<>();
        if (!CheckUtil.objIsEmpty(oaApprovalTempChildList)) {
            for (OaApprovalTempChild otc : oaApprovalTempChildList) {
                ApprovalTempNodeInfo approvalTempNodeInfo = new ApprovalTempNodeInfo();
                if (otc.getIsParallel() == 0) {
                    approvalTempNodeInfo.setChecked(false);
                } else if (otc.getIsParallel() == 1) {
                    approvalTempNodeInfo.setChecked(true);
                }
                approvalTempNodeInfo.setType(String.valueOf(otc.getApproverType()));
                approvalTempNodeInfo.setUserIds(otc.getApproverId());
                approvalTempNodeInfo.setInitiator(otc.getExpand1());
                approvalTempNodeInfo.setName(otc.getExpand2());
                nodeList.add(approvalTempNodeInfo);
            }
        }
        approvalTempInfoParam.setNodeList(nodeList);
        return Rv.wrap(approvalTempInfoParam);
    }
}
